/********************************************************************************/
/*   The  Software  is  proprietary,  confidential,  and  valuable to Realtek   */
/*   Semiconductor  Corporation  ("Realtek").  All  rights, including but not   */
/*   limited  to  copyrights,  patents,  trademarks, trade secrets, mask work   */
/*   rights, and other similar rights and interests, are reserved to Realtek.   */
/*   Without  prior  written  consent  from  Realtek,  copying, reproduction,   */
/*   modification,  distribution,  or  otherwise  is strictly prohibited. The   */
/*   Software  shall  be  kept  strictly  in  confidence,  and  shall  not be   */
/*   disclosed to or otherwise accessed by any third party.                     */
/*   c<2003> - <2012>                                                           */
/*   The Software is provided "AS IS" without any warranty of any kind,         */
/*   express, implied, statutory or otherwise.                                  */
/********************************************************************************/

//----------------------------------------------------------------------------------------------------
// ID Code      : DeviceLedDriver\02_AS_AS3820.c
// Update Note  :
//----------------------------------------------------------------------------------------------------

#include "UserCommonInclude.h"

#if(_DEVICE_LED_DRIVER_TYPE == _DEVICE_LED_DRIVER_02_AUSTRIA_AS3820)
#if(_LOCAL_DIMMING_SUPPORT == _ON)

//****************************************************************************
// DEFINITIONS / MACROS
//****************************************************************************
//--------------------------------------------------
// Definitions of debug I2C command type
//--------------------------------------------------
#define _DEBUG_I2C_SLAVE                            2
#define _DEBUG_I2C_SUB                              1
#define _DEBUG_I2C_DATA                             3

//--------------------------------------------------
// Device Address
//--------------------------------------------------
#define _DEVICE_LED_DRIVER_DEVICE_ADDRESS_DEBUG     0x1A
#define _DEVICE_LED_DRIVER_DEVICE_ADDRESS           0x01

//--------------------------------------------------
// Single Byte
//--------------------------------------------------
#define _DEVICE_LED_DRIVER_SINGLE_DATA              _BIT6
#define _DEVICE_LED_DRIVER_BLOCK_DATA               0x00

//--------------------------------------------------
// Read / Write
//--------------------------------------------------
#define _DEVICE_LED_DRIVER_READ                     _BIT7
#define _DEVICE_LED_DRIVER_WRITE                    0x00

//--------------------------------------------------
// PWM Plus Width
//--------------------------------------------------
#define _REG_ADDRESS_PWM1_PLUS_WIDTH_LSB            0x37
#define _REG_ADDRESS_PWM1_PLUS_WIDTH_MSB            0x38
#define _REG_ADDRESS_PWM2_PLUS_WIDTH_LSB            0x39
#define _REG_ADDRESS_PWM2_PLUS_WIDTH_MSB            0x3A
#define _REG_ADDRESS_PWM3_PLUS_WIDTH_LSB            0x3B
#define _REG_ADDRESS_PWM3_PLUS_WIDTH_MSB            0x3C
#define _REG_ADDRESS_PWM4_PLUS_WIDTH_LSB            0x3D
#define _REG_ADDRESS_PWM4_PLUS_WIDTH_MSB            0x3E
#define _REG_ADDRESS_PWM5_PLUS_WIDTH_LSB            0x3F
#define _REG_ADDRESS_PWM5_PLUS_WIDTH_MSB            0x40
#define _REG_ADDRESS_PWM6_PLUS_WIDTH_LSB            0x41
#define _REG_ADDRESS_PWM6_PLUS_WIDTH_MSB            0x42
#define _REG_ADDRESS_PWM7_PLUS_WIDTH_LSB            0x43
#define _REG_ADDRESS_PWM7_PLUS_WIDTH_MSB            0x44
#define _REG_ADDRESS_PWM8_PLUS_WIDTH_LSB            0x45
#define _REG_ADDRESS_PWM8_PLUS_WIDTH_MSB            0x46
#define _REG_ADDRESS_PWM9_PLUS_WIDTH_LSB            0x47
#define _REG_ADDRESS_PWM9_PLUS_WIDTH_MSB            0x48
#define _REG_ADDRESS_PWM10_PLUS_WIDTH_LSB           0x49
#define _REG_ADDRESS_PWM10_PLUS_WIDTH_MSB           0x4A
#define _REG_ADDRESS_PWM11_PLUS_WIDTH_LSB           0x4B
#define _REG_ADDRESS_PWM11_PLUS_WIDTH_MSB           0x4C
#define _REG_ADDRESS_PWM12_PLUS_WIDTH_LSB           0x4D
#define _REG_ADDRESS_PWM12_PLUS_WIDTH_MSB           0x4E
#define _REG_ADDRESS_PWM13_PLUS_WIDTH_LSB           0x4F
#define _REG_ADDRESS_PWM13_PLUS_WIDTH_MSB           0x50
#define _REG_ADDRESS_PWM14_PLUS_WIDTH_LSB           0x51
#define _REG_ADDRESS_PWM14_PLUS_WIDTH_MSB           0x52
#define _REG_ADDRESS_PWM15_PLUS_WIDTH_LSB           0x53
#define _REG_ADDRESS_PWM15_PLUS_WIDTH_MSB           0x54
#define _REG_ADDRESS_PWM16_PLUS_WIDTH_LSB           0x55
#define _REG_ADDRESS_PWM16_PLUS_WIDTH_MSB           0x56


//****************************************************************************
// MACROS
//****************************************************************************


//****************************************************************************
// STRUCT
//****************************************************************************


//****************************************************************************
// TYPE / ENUM DEFINITTIONS
//****************************************************************************


//****************************************************************************
// CODE TABLES
//****************************************************************************


//****************************************************************************
// VARIABLE DECLARATIONS
//****************************************************************************


//****************************************************************************
// FUNCTION DECLARATIONS
//****************************************************************************
#if(_DEBUG_IIC_BY_USERINTERFACE == _ON)
bit DeviceLedDriverDebug(BYTE ucType, BYTE *ucDdcciArray, BYTE *ucReturnValue);
#endif
void DeviceLedDriverInitial(void);
void DeviceLedDriverPwmEnable(bit bEnable);
void DeviceLedDriverPwm(EnumDeviceLedDriverPwm enumDeviceLedDriverPwm, WORD usValue);
void DeviceLedDriverPwmArray(WORD *usValue);
void DeviceLedDriverBacklight(WORD usBacklight);


//****************************************************************************
// FUNCTION DEFINITIONS
//****************************************************************************
#if(_DEBUG_IIC_BY_USERINTERFACE == _ON)
//--------------------------------------------------
// Description  : Set Led Driver Debug
// Input Value  : None
// Output Value : None
//--------------------------------------------------
bit DeviceLedDriverDebug(BYTE ucType, BYTE *ucDdcciArray, BYTE *ucReturnValue)
{
    BYTE ucRegData[10] = {0};

    if(*(ucDdcciArray + _DEBUG_I2C_SLAVE) != _DEVICE_LED_DRIVER_DEVICE_ADDRESS_DEBUG)
    {
        return _FALSE;
    }

    if(ucType == _READ)
    {
        ucRegData[0] = (_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA);
        ucRegData[1] = (*(ucDdcciArray + _DEBUG_I2C_SUB) | _DEVICE_LED_DRIVER_READ);

#if(_SPI_SUPPORT == _ON)
        ScalerSpiData(_READ, 2, ucRegData);
#endif

        *ucReturnValue = ucRegData[1];
    }
    else if(ucType == _WRITE)
    {
        ucRegData[0] = (_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA);
        ucRegData[1] = *(ucDdcciArray + _DEBUG_I2C_SUB);
        ucRegData[2] = *(ucDdcciArray + _DEBUG_I2C_DATA);

#if(_SPI_SUPPORT == _ON)
        ScalerSpiData(_WRITE, 3, ucRegData);
#endif
    }

    return _TRUE;
}
#endif

//--------------------------------------------------
// Description  : Set Led Driver Initial
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void DeviceLedDriverInitial(void)
{
    BYTE device_01[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x36, 0xCA};
    BYTE device_02[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x13, 0x40};
    BYTE device_03[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x14, 0xFF};
    BYTE device_04[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x15, 0x0F};
    BYTE device_05[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x01, 0xFF};
    BYTE device_06[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x02, 0xFF};

    BYTE device_07[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x61, 0x1F};
    BYTE device_08[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x62, 0xFF};

    BYTE device_09[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x0C, 0xA7};
    BYTE device_10[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x0D, 0x02};
    BYTE device_11[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x07, 0x04};
    BYTE device_12[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x0E, 0xFF};

#if(_SPI_SUPPORT == _ON)
    ScalerSpiInitial();
#endif

#if(_SPI_SUPPORT == _ON)
    ScalerSpiData(_WRITE, 3, device_01);
    ScalerSpiData(_WRITE, 3, device_02);
    ScalerSpiData(_WRITE, 3, device_03);
    ScalerSpiData(_WRITE, 3, device_04);
    ScalerSpiData(_WRITE, 3, device_05);
    ScalerSpiData(_WRITE, 3, device_06);

    ScalerSpiData(_WRITE, 3, device_09);
    ScalerSpiData(_WRITE, 3, device_10);
    ScalerSpiData(_WRITE, 3, device_11);
    ScalerSpiData(_WRITE, 3, device_12);

    ScalerSpiData(_WRITE, 3, device_07);
    ScalerSpiData(_WRITE, 3, device_08);
#endif
}


//--------------------------------------------------
// Description  : Set Led Driver Pwm Enable/Disable
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void DeviceLedDriverPwmEnable(bit bEnable)
{
    BYTE device_77[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x01, 0xFF};
    BYTE device_78[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x02, 0xFF};

    BYTE device_lock[3]   = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x36, 0xAC};
    BYTE device_unlock[3] = {(_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_SINGLE_DATA), 0x36, 0xCA};

    if(bEnable == _ENABLE)
    {
#if(_SPI_SUPPORT == _ON)
        ScalerSpiData(_WRITE, 3, device_unlock);
        ScalerSpiData(_WRITE, 3, device_77);
        ScalerSpiData(_WRITE, 3, device_78);
        ScalerSpiData(_WRITE, 3, device_lock);
#endif

        //UserAdjustBacklight(GET_OSD_BACKLIGHT());
        UserAdjustBacklightProcess();
    }
    else
    {
        DeviceLedDriverPwm(_PANEL_PWM_LOCAL_ALL, 0x0000);
    }
}


//--------------------------------------------------
// Description  : Set Led Driver Pwm Duty
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void DeviceLedDriverPwm(EnumDeviceLedDriverPwm enumDeviceLedDriverPwm, WORD usValue)
{
    BYTE i = 0;
    BYTE ucTemp[3 + ((_PANEL_PWM_LOCAL_END - _PANEL_PWM_LOCAL_START + 1) * 2)] = {0};
    BYTE ucLength = 0;
    BYTE j = 0;
    BYTE k[3] = {0};

    if(enumDeviceLedDriverPwm == _PANEL_PWM_LOCAL_ALL)
    {
        ucLength = (_PANEL_PWM_LOCAL_END - _PANEL_PWM_LOCAL_START + 1);
        enumDeviceLedDriverPwm = _PANEL_PWM_LOCAL_START;
        ucTemp[1] = 16;
    }
    else
    {
        ucLength = 1;
        ucTemp[1] = 2;
    }

    ucTemp[0] = (_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_BLOCK_DATA);
    ucTemp[2] = ((enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_1) ? _REG_ADDRESS_PWM1_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_2) ? _REG_ADDRESS_PWM2_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_3) ? _REG_ADDRESS_PWM3_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_4) ? _REG_ADDRESS_PWM4_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_5) ? _REG_ADDRESS_PWM5_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_6) ? _REG_ADDRESS_PWM6_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_7) ? _REG_ADDRESS_PWM7_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_8) ? _REG_ADDRESS_PWM8_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_9) ? _REG_ADDRESS_PWM9_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_10) ? _REG_ADDRESS_PWM10_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_11) ? _REG_ADDRESS_PWM11_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_12) ? _REG_ADDRESS_PWM12_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_13) ? _REG_ADDRESS_PWM13_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_14) ? _REG_ADDRESS_PWM14_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_15) ? _REG_ADDRESS_PWM15_PLUS_WIDTH_LSB :
                 (enumDeviceLedDriverPwm == _DEVICE_LED_DRIVER_PWM_16) ? _REG_ADDRESS_PWM16_PLUS_WIDTH_LSB : _REG_ADDRESS_PWM1_PLUS_WIDTH_LSB);

    usValue = ((usValue > _PANEL_PWM_MAX) ? _PANEL_PWM_MAX :
              ((usValue < _PANEL_PWM_MIN) ? _PANEL_PWM_MIN : usValue));

    for(i = 0; i < ucLength; i++)
    {
        ucTemp[3 + (i * 2)] = (usValue & 0x00FF);
        ucTemp[4 + (i * 2)] = ((usValue & 0x0F00) >> 8);
    }

    ucLength = 3 + (ucLength * 2);

#if(_SPI_SUPPORT == _ON)
    ScalerSpiData(_WRITE, ucLength, ucTemp);
#endif
}


//--------------------------------------------------
// Description  : Set Led Driver Pwm Frequency
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void DeviceLedDriverPwmArray(WORD *usValue)
{
    BYTE i = 0;
    BYTE j = 0;

    BYTE ucTemp[3 + ((_PANEL_PWM_LOCAL_END - _PANEL_PWM_LOCAL_START + 1) * 2)] = {0};
    BYTE ucLength = (_PANEL_PWM_LOCAL_END - _PANEL_PWM_LOCAL_START + 1);

    BYTE code tPAANEL_LOCAL_PWM_TYPE[]  = { _PANEL_PWM_LOCAL_1,  _PANEL_PWM_LOCAL_2,  _PANEL_PWM_LOCAL_3,  _PANEL_PWM_LOCAL_4,
                                            _PANEL_PWM_LOCAL_5,  _PANEL_PWM_LOCAL_6,  _PANEL_PWM_LOCAL_7,  _PANEL_PWM_LOCAL_8,
                                            _PANEL_PWM_LOCAL_9,  _PANEL_PWM_LOCAL_10, _PANEL_PWM_LOCAL_11, _PANEL_PWM_LOCAL_12,
                                            _PANEL_PWM_LOCAL_13, _PANEL_PWM_LOCAL_14, _PANEL_PWM_LOCAL_15, _PANEL_PWM_LOCAL_16,
                                          };

    ucTemp[0] = (_DEVICE_LED_DRIVER_DEVICE_ADDRESS | _DEVICE_LED_DRIVER_BLOCK_DATA);
    ucTemp[1] = 16;
    ucTemp[2] = ((_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_1) ? _REG_ADDRESS_PWM1_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_2) ? _REG_ADDRESS_PWM2_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_3) ? _REG_ADDRESS_PWM3_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_4) ? _REG_ADDRESS_PWM4_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_5) ? _REG_ADDRESS_PWM5_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_6) ? _REG_ADDRESS_PWM6_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_7) ? _REG_ADDRESS_PWM7_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_8) ? _REG_ADDRESS_PWM8_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_9) ? _REG_ADDRESS_PWM9_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_10) ? _REG_ADDRESS_PWM10_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_11) ? _REG_ADDRESS_PWM11_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_12) ? _REG_ADDRESS_PWM12_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_13) ? _REG_ADDRESS_PWM13_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_14) ? _REG_ADDRESS_PWM14_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_15) ? _REG_ADDRESS_PWM15_PLUS_WIDTH_LSB :
                 (_PANEL_PWM_LOCAL_START == _DEVICE_LED_DRIVER_PWM_16) ? _REG_ADDRESS_PWM16_PLUS_WIDTH_LSB : _REG_ADDRESS_PWM1_PLUS_WIDTH_LSB);


    for(i = 0; i < ucLength; i++)
    {
        PDATA_DWORD(0) = 0;

        for(j = 0; j < sizeof(tPAANEL_LOCAL_PWM_TYPE); j++)
        {
            if((_PANEL_PWM_LOCAL_START + i) == tPAANEL_LOCAL_PWM_TYPE[j])
            {
                PDATA_DWORD(0) = ((*(usValue + j) > _DEVICE_LED_DRIVER_PWM_MAX) ? _DEVICE_LED_DRIVER_PWM_MAX : *(usValue + j));
                break;
            }
        }

        ucTemp[3 + (i * 2)] = (PDATA_DWORD(0) & 0x00FF);
        ucTemp[4 + (i * 2)] = ((PDATA_DWORD(0) & 0x0F00) >> 8);
    }

    ucLength = 3 + (ucLength * 2);

#if(_SPI_SUPPORT == _ON)
    ScalerSpiSPIDataCeForceLow(_WRITE, ucLength, ucTemp);
#endif
}


//--------------------------------------------------
// Description  : Adjust Backlight
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void DeviceLedDriverBacklight(WORD usBacklight)
{
    usBacklight = (((DWORD)(usBacklight - _BACKLIGHT_MIN) * (_DEVICE_LED_DRIVER_PWM_MAX- _DEVICE_LED_DRIVER_PWM_MIN)) / (_BACKLIGHT_MAX - _BACKLIGHT_MIN)) + _DEVICE_LED_DRIVER_PWM_MIN;

    DeviceLedDriverPwm(_PANEL_PWM_LOCAL_ALL, usBacklight);
}
#endif // End of #if(_LOCAL_DIMMING_SUPPORT == _ON)
#endif // End of #if(_DEVICE_LED_DRIVER_TYPE == _DEVICE_LED_DRIVER_02_AUSTRIA_AS3820)

